;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
;                                          All Rights Reserved
;
;
;                                           Renesas SH-2A-FPU
;                               Renesas SH SERIES C/C++ Compiler (V.9.00.03.006)
;
;
;
; File : OS_CPU_A.SRC
;********************************************************************************************************
;Include OS_CTX_SAVE and OS_CTX_RESTORE macros
        #include    "os_cpu_a.inc"         
        
        
        PUBLIC     _OS_Get_GBR
        PUBLIC     _OSStartHighRdy
        PUBLIC     _OSCtxSw
        PUBLIC     _OSIntCtxSw
        PUBLIC     _OSTickISR
        EXTERN     _OSTaskSwHook
        EXTERN     _OSTCBHighRdy
        EXTERN     _OSRunning
        EXTERN     _OSTCBCur
        EXTERN     _OSPrioCur
        EXTERN     _OSPrioHighRdy
        EXTERN     _OSIntEnter
        EXTERN     _OSTimeTick
        EXTERN     _OSIntExit
        EXTERN     _OSIntNesting
        EXTERN     _TickClr                    ; implement your own function to clear 
                                           ; the OS tick source

        SECTION    __DEFAULT_CODE_SECTION__:CODE:NOROOT(2)


;********************************************************************************************************
;                                            OS_Get_GBR()
;********************************************************************************************************

_OS_Get_GBR:
        stc   gbr,   r0
        rts
        nop
        
        
;********************************************************************************************************
;                                            OSStartHighRdy()
;********************************************************************************************************

_OSStartHighRdy:
        mov.l   #_OSTaskSwHook, r1          ; address of OSTaskSwHook function in R1
        jsr     @r1                         ; call OSTaskSwHook()
        nop

        mov.l   #_OSTCBHighRdy, r1          ; address of OSTCBHighRdy in R1
        mov.l   @r1, r2                     ; r2 is now the address of the ready task
        mov.l   @r2, r15                    ; stack pointer = OSTCBHighRdy->OstcBStkptr

        mov.l   #_OSRunning, r1             ; address of OSRunning in R1
        mov     #1, r2                      ; OSRunning = TRUE (1)
        mov.b   r2, @r1

        OS_CTX_RESTORE                      ; restore all processor registers from new task's stack

        rte                                 ; return from interrupt
        nop


;********************************************************************************************************
;                                                OSCtxSw()
;********************************************************************************************************

_OSCtxSw:
        OS_CTX_SAVE                         ; save processor registers on the stack

                                            ; save current task's stack pointer into current task's OS_TCB
        mov.l   #_OSTCBCur, r0              ; get address of OSTCBCur
        mov.l   @r0, r3                     ; R3 contains address of current TCB
        mov.l   r15, @r3                    ; put stack pointer into it

        mov.l   #_OSTaskSwHook, r2
        jsr     @r2                         ; call OSTaskSWHook
        nop

        mov.l   #_OSTCBCur, r0              ; get address of OSTCBCur
        mov.l   #_OSTCBHighRdy, r1          ; get address of OSTCBHighRdy
        mov.l   @r1, r3
        mov.l   r3, @r0                     ; OSTCBCur = OSTCBHighRdy

        mov.l   #_OSPrioCur, r0             ; get address of OSPrioCur
        mov.l   #_OSPrioHighRdy, r2         ; get address of OSPrioHighRdy
        mov.b   @r2, r3
        mov.b   r3, @r0

        mov.l   @r1, r2                     ; r2 contains address of current TCB
        mov.l   @r2, r15                    ; stack pointer = OSTCBHighRdy->OstcBStkPtr

        OS_CTX_RESTORE                      ; restore all processor registers from new task's stack
        
        rte
        nop


;********************************************************************************************************
;                                               OSIntCtxSw()
;********************************************************************************************************
_OSIntCtxSw:
        mov.l   #_OSTaskSwHook, r2
        jsr     @r2                         ; call OSTaskSWHook
        nop

        mov.l   #_OSPrioHighRdy, r2         ; get address of OSPrioHighRdy
        mov.l   #_OSPrioCur, r0             ; get address of OSPrioCur
        mov.b   @r2, r3
        mov.b   r3, @r0                     ; OSPrioCur = OSPrioHighRdy

        mov.l   #_OSTCBHighRdy, r1          ; get address of OSTCBHighRdy
        mov.l   #_OSTCBCur, r0              ; get address of OSTCBCur
        mov.l   @r1, r3
        mov.l   r3, @r0                     ; OSTCBCur = OSTCBHighRdy
        
        mov.l   @r3, r15                    ; CPU stack pointer = OSTCBHighRdy->OstcBStkPtr

        OS_CTX_RESTORE                      ; restore all processor registers from new task's stack
        
        rte
        nop


;********************************************************************************************************
;                                                OSTickISR()
;********************************************************************************************************
_OSTickISR:       
        OS_CTX_SAVE                         ; save processor registers on the stack

        mov.l   #_OSIntNesting, r1          ; Load BN to OSIntNesting
        mov.l   #IBNR, r2                   ; 
        mov.w   @r2, r0
        extu.b  r0, r0
        mov.b   r0, @r1                     ; If OSIntNesting == 1 save the current stack pointer              
        tst     #1, r0                      ; onto the current task's stack
        bt      _OSTickISR1

        mov.l   #_OSTCBCur, r1              ; Save current task's SP into its TCB
        mov.l   @r1, r0
        mov.l   r15, @r0
        
_OSTickISR1:    
	RESBANK                             ; Restoring from Bank, BN-1
        mov.l   #_TickClr, r3               ; clear timer interrupt source
        jsr     @r3
        nop

        mov.l   #_OSTimeTick, r0
        jsr     @r0                         ; call OSTimeTick()
        nop
        
        mov.l   #_OSIntExit, r0
        jsr     @r0                         ; call OSIntExit()
        nop

        OS_CTX_RESTORE                      ; restore all processor registers from stack
        
        rte
        nop

        END
        